/**   
 * @Title: StringTools.java 
 * @Package com.org.utils 
 * @Description: TODO(用一句话描述该文件做什么) 
 * @author cssuger@163.com   
 * @date 2016年5月24日 下午4:47:11 
 * @version V1.0   
 */
package com.bicon.base.data.common;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

/**
 * @ClassName: StringTools
 * @Description: 字符串常用处理方法
 * 
 */
public class StringTools {

	/**
	 * 
	 * @Title: mkString
	 * @Description: 讲null 或者""转换为"" @param @param str
	 * @return String 返回类型 @throws
	 */
	public static String mkString(final String str) {
		
		String res = StringUtils.trimToEmpty(str);
		return StringUtils.equals("null", res) ? "" : res;
	}
	
	public static String mkString(final String str,String defalutValues) {
		boolean isNull = isBlank(str);
		return isNull?defalutValues:mkString(str);
	}

	/**
	 * 
	 * @Title: isBlank
	 * @Description: 判断该字符串是否为""，如果为""返回true，否则返货false
	 * @param @param
	 * @return boolean 返回类型 @throws
	 */
	public static boolean isBlank(final String str) {
		return StringUtils.isBlank(mkString(str));
	}

	/**
	 * 
	 * @Title: dateNow
	 * @Description: 获取当前时间
	 * @param @param formate日期格式化
	 * @param @return 设定文件
	 * @return String 返回类型
	 * @throws
	 */
	public static String dateNow(String formate) {
		SimpleDateFormat dateformate = new SimpleDateFormat(formate);
		return dateformate.format(new Date());
	}
	
	
	/**
	 * 
	 * @Title: hasString
	 * @Description: 判断字符串里面是否存在某个给定的字符串
	 * @param @param formate日期格式化
	 * @param @return 设定文件
	 * @return String 返回类型
	 * @throws
	 */
	public static boolean hasString(String src,String str) {
		int index = StringUtils.indexOf(src, str); 
		return index> -1 ?true:false;
	}

	public static boolean isNmber(String number) {
		return NumberUtils.isDigits(number);

	}

	/**
	 * 
	 * @Title: beanCopy @Description: bean 拷贝 @param @param dist 目标对象 @param @param
	 *         org 原始对象 @return void 返回类型 @throws
	 */
	public static void beanCopy(Object dest, Object orig) {
		try {
			BeanUtils.copyProperties(dest, orig);
		} catch (IllegalAccessException | InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @Title: beanToMap @Description: 将bean转换为map集合 @param @param bean @param @return
	 *         设定文件 @return Map<String,String> 返回类型 @throws
	 */
	public static Map<String, Object> beanToMap(Object bean) {
		try {

			return PropertyUtils.describe(bean);
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 
	 * @Title: map2Bean @Description: 将map转换为bean @param @param map @param @param
	 *         class1 @param @return 设定文件 @return T 返回类型 @throws
	 */
	public static <T> T map2Bean(Map<String, String> map, Class<T> class1) {
		T bean = null;
		try {
			bean = class1.newInstance();
			BeanUtils.populate(bean, map);
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return bean;
	}

	/**
	 * 字符串不足位数 右补空格
	 * 
	 * @param str
	 * @param strLength
	 */
	public static String addSpaceForStr_R(String str, int strLength) {
		int strLen = strLength(str);
		if (strLen < strLength) {
			if (StringUtils.isBlank(str)) {
				str = "";
			}
			while (strLen < strLength) {
				StringBuffer sb = new StringBuffer();
				sb.append(str).append(" ");// 空格
				// sb.append(" ").append(str);//左补
				str = sb.toString();
				strLen += 1;
			}
		}
		return str;
	}

	/**
	 * 字符串不足位数 右补0
	 * 
	 * @param str
	 * @param strLength
	 */
	public static String addZeroForStr_R(String str, int strLength) {
		int strLen = strLength(str);
		if (strLen < strLength) {
			while (strLen < strLength) {
				StringBuffer sb = new StringBuffer();
				if (StringUtils.isNotBlank(str)) {
					sb.append(str).append(Constants.ZERO_NUMBER);// 右补
				} else {
					sb.append(Constants.ZERO_NUMBER);
				}

				// sb.append(" ").append(str);//左补
				str = sb.toString();
				strLen += 1;
			}
		}
		return str;
	}

	/**
	 * 字符串不足位数 左补空格
	 * 
	 * @param str
	 * @param strLength
	 */
	public static String addSpaceForStr_L(String str, int strLength) {
		int strLen = strLength(str);
		if (strLen < strLength) {
			if (StringUtils.isBlank(str)) {
				str = "";
			}
			while (strLen < strLength) {
				StringBuffer sb = new StringBuffer();
				// sb.append(str).append(" ");//空格
				sb.append(" ").append(str);// 左补
				str = sb.toString();
				strLen += 1;
			}
		}
		return str;
	}

	/**
	 * 字符串不足位数 左补0
	 * 
	 * @param str
	 * @param strLength
	 */
	public static String addZeroForStr_L(String str, int strLength) {
		int strLen = strLength(str);
		if (strLen < strLength) {
			while (strLen < strLength) {
				StringBuffer sb = new StringBuffer();
				// sb.append(str).append("0");//右补
				if (StringUtils.isNotBlank(str)) {
					sb.append(Constants.ZERO_NUMBER).append(str);// 左补
				} else {
					sb.append(Constants.ZERO_NUMBER);
				}
				str = sb.toString();
				strLen += 1;
			}
		}
		return str;
	}

	/**
	 * 字符串不足位数 左补指定字符
	 * 
	 * @param str
	 * @param strLength
	 */
	public static String addForStr_L(String str, String s, int strLength) {
		int strLen = strLength(str);
		if (strLen < strLength) {
			while (strLen < strLength) {
				StringBuffer sb = new StringBuffer();
				sb.append(s).append(str);// 左补
				str = sb.toString();
				strLen += 1;
			}
		}
		return str;
	}

	/**
	 * 获取字符串长度(字符串中可包含中文)
	 * 
	 * @param str
	 * @return
	 */
	public static int strLength(String str) {
		int valueLength = 0;
		String chinese = "[\u0391-\uFFE5]";
		/* 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1 */
		if (StringUtils.isNotBlank(str)) {
			for (int i = 0; i < str.length(); i++) {
				/* 获取一个字符 */
				String temp = str.substring(i, i + 1);
				/* 判断是否为中文字符 */
				if (temp.matches(chinese)) {
					/* 中文字符长度为2 */
					valueLength += 2;
				} else {
					/* 其他字符长度为1 */
					valueLength += 1;
				}
			}
		}

		return valueLength;
	}

	/**
	 * 字符串不足位数 右补指定字符
	 * 
	 * @param str
	 * @param strLength
	 */
	public static String addForStr_R(String str, String s, int strLength) {
		int strLen = strLength(str);
		if (strLen < strLength) {
			while (strLen < strLength) {
				StringBuffer sb = new StringBuffer();
				sb.append(str).append(s);// 右补
				str = sb.toString();
				strLen += 1;
			}
		}
		return str;
	}

	/**
	 * 补齐不足长度
	 * 
	 * @param length长度
	 * @param number数字
	 * @return
	 */
	public static String lpad(int number, int length) {
		String f = "%0" + length + "d";
		return String.format(f, number);
	}

	public static String addValueToLength_R(String source, String type, int length) {
		String ret = "";
		if (source == null || "".equals(source)) {
			if (Constants.ZERO_STRING.equals(type)) {
				ret = StringTools.addZeroForStr_R(ret, length);
			} else if (Constants.SPACE_STRING.equals(type)) {
				ret = StringTools.addSpaceForStr_R(ret, length);
			}
		} else {
			if (Constants.ZERO_STRING.equals(type)) {
				ret = StringTools.addZeroForStr_R(source, length);
			} else if (Constants.SPACE_STRING.equals(type)) {
				ret = StringTools.addSpaceForStr_R(source, length);
			}

		}
		return ret;
	}

	public static String addValueToLength_L(String source, String type, int length) {
		String ret = "";
		if (source == null || "".equals(source)) {
			if (Constants.ZERO_STRING.equals(type)) {
				ret = StringTools.addZeroForStr_L(ret, length);
			} else if (Constants.SPACE_STRING.equals(type)) {
				ret = StringTools.addSpaceForStr_L(ret, length);
			}
		} else {
			if (Constants.ZERO_STRING.equals(type)) {
				ret = StringTools.addZeroForStr_L(source, length);
			} else if (Constants.SPACE_STRING.equals(type)) {
				ret = StringTools.addSpaceForStr_L(source, length);
			}
		}
		return ret;
	}

	/**
	 * 字符串截取(字符串可包含中文) 截取从指定开始位置和指定结束位置的字符串
	 * 
	 * @param source
	 *            源字符串
	 * @param start
	 *            截取的起始位置
	 * @param end
	 *            截取结束位置
	 * @return
	 */
	public static String subString(String source, int start, int end, String encode) {
		try {
			source = new String(source.getBytes(encode), "ISO-8859-1");
			return new String(source.substring(start, end).getBytes("ISO-8859-1"), encode);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 字符串截取(字符串可包含中文) 截取从指定开始位置和指定结束位置的字符串
	 * 
	 * @param source
	 *            源字符串
	 * @param start
	 *            截取的起始位置
	 * @param end
	 *            截取结束位置
	 * @return
	 */
	public static String subString(String source, int start, int end) {
		return StringUtils.substring(source, start, end);
	}

	/**
	 * 字符串截取(字符串可包含中文 UTF-8) 截取从指定开始位置和指定结束位置的字符串
	 * 
	 * @param source
	 *            源字符串
	 * @param start
	 *            截取的起始位置
	 * @param end
	 *            截取结束位置
	 * @return
	 */
	public static String subChString(String source, int start, int end) {
		try {
			source = new String(source.getBytes("UTF-8"), "UTF-8");
			return new String(source.substring(start, end).getBytes("UTF-8"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static int getBegin(int begin, String sss) {
		if (begin == 0) {
			return 0;
		}
		char[] c = sss.toCharArray();
		int len = 0;
		for (int i = 0; i < c.length; i++) {
			len++;
			if (!isLetter(c[i])) {
				len++;
			}
			if (len == begin) {
				return i;
			}
		}
		return len;
	}

	public static int getEnd(int end, String sss) {
		if (end == 0) {
			return 0;
		}
		char[] c = sss.toCharArray();
		int len = 0;
		for (int i = 0; i < c.length; i++) {
			len++;
			if (!isLetter(c[i])) {
				len++;
			}
			if (len == end) {
				return i;
			}
		}

		return len;
	}

	public static int length(String s) {
		if (s == null)
			return 0;
		char[] c = s.toCharArray();
		int len = 0;
		for (int i = 0; i < c.length; i++) {
			len++;
			if (!isLetter(c[i])) {
				len++;
			}
		}
		return len;
	}

	/*
	 * 偏移位置（一个中文一个汉字），长度（1一个汉字两个），源文件， （最后优化，最优，适合截图记录）
	 */
	public static String subChString(int offset, int length, String s) {
		if (s == null || length == 0)
			return "";
		char[] c = s.toCharArray();
		int len = 0;
		int i = offset;
		for (i = offset; i < s.length(); i++) {
			len++;
			if (!isLetter(c[i])) {
				len++;
			}
			if (len == length - offset) {
				break;// 此时的i就是substring的截止
			}
		}
		return s.substring(offset, i + 1);
	}

	/*
	 * 测试
	 */
	public static String subChs(int begin, int end, String s) {
		if (s == null || end - begin == 0)
			return "";
		char[] c = s.toCharArray();
		char[] r = new char[end - begin];
		for (int i = begin; i < end - begin; i++) {
			if (!isLetter(c[i])) {
				continue;
			} else {
				r[i] = c[i];
			}
		}
		System.out.println(r.length);
		return new String(r);
	}

	/*
	 * 获取中文字段个数
	 */
	public static int getChNum(String s) {
		if (s == null)
			return 0;
		char[] c = s.toCharArray();
		int len = 0;
		for (int i = 0; i < c.length; i++) {
			if (!isLetter(c[i])) {
				len++;
			}
		}
		return len;
	}

	public static boolean isLetter(char c) {
		int k = 0x80;
		return c / k == 0 ? true : false;
	}

	// private static boolean isChinens(char c)throws
	// UnsupportedEncodingException {
	// if (String.valueOf(c).getBytes("GB2312").length > 1) {
	// return true;
	// } else {
	// return false;
	// }
	// }

	// 优化后的
	public static String subString(int begin, int end, String source) {
		String ret = "";
		if (end > length(source))
			end = length(source);
		try {
			byte[] bytes = source.getBytes(Constants.GB2312_STR);
			byte[] str = new byte[end - begin];// 要截取的字节码
			int index = 0;
			for (int i = begin; i < end; i++) {
				str[index++] = bytes[i];// 获取100-130的字节码
			}
			ret = new String(str, Constants.GB2312_STR);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return ret;
	}

	/**
	 * 字符串截取(字符串可包含中文) 截取从指定开始位置和指定结束位置的字符串
	 * 
	 * @param source
	 *            源字符串
	 * @param start
	 *            截取的起始位置
	 * @param end
	 *            截取结束位置
	 * @return
	 */
	public static String subStr(String source, int start, int end) {
		try {
			source = new String(source.getBytes(Constants.GBK_ENCODE_FORMATE), Constants.NUMBER_FORMATE);
			return new String(source.substring(start, end).getBytes(Constants.NUMBER_FORMATE), Constants.GBK_ENCODE_FORMATE);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 字符串截取(字符串可包含中文) 截取从指定位置开始的指定长度的字符串
	 * 
	 * @param source
	 *            源字符串
	 * @param start
	 *            截取的起始位置
	 * @param end
	 *            截取长度
	 * @return
	 */
	public static String subStringSpecifiedLength(String source, int start, int count) {
		int end = start + count;
		return subString(source, start, end);
	}

	/**
	 * 字节数组转十六进制字符串
	 * 
	 * @param ba
	 *            原数据
	 * @param offset
	 *            开始位移
	 * @param length
	 *            长度
	 * @return 16进制字符串
	 */
	public final static String ba2HexString(byte[] ba, int offset, int length) {
		char[] buf = new char[length << 1];
		for (int i = 0, j = 0, k; i < length;) {
			k = ba[offset + i++];
			buf[j++] = Constants.HEX_DIGITS[(k >>> 4) & 0x0F];
			buf[j++] = Constants.HEX_DIGITS[k & 0x0F];
		}
		return new String(buf);
	}

	/**
	 * 16进制字符串转字节数组
	 * 
	 * @param s
	 *            16进制字符串
	 * @return 字节数组
	 */
	public final static byte[] hexString2Ba(String s) {
		if (s == null || s.length() == 0) {
			return null;
		}
		int limit = s.length();
		byte[] result = new byte[((limit + 1) / 2)];
		int i = 0, j = 0;
		if ((limit % 2) == 1) {
			result[j++] = (byte) char2Byte(s.charAt(i++));
		}
		while (i < limit) {
			result[j] = (byte) (char2Byte(s.charAt(i++)) << 4);
			result[j++] |= (byte) char2Byte(s.charAt(i++));
		}
		return result;
	}

	/*
	 * 字符转字节
	 * 
	 * @param c
	 * 
	 * @return
	 */
	private static byte char2Byte(char c) {
		if (c >= '0' && c <= '9') {
			return (byte) (c - '0');
		} else if (c >= 'A' && c <= 'F') {
			return (byte) (c - 'A' + 10);
		} else if (c >= 'a' && c <= 'f') {
			return (byte) (c - 'a' + 10);
		} else
			throw new IllegalArgumentException("Invalid hexadecimal digit: " + c);
	}

	// 优化前的做个备份
	public static String subBufString(int begin, int end, String source) {
		String ret = "";
		if (end > length(source)) {
			end = length(source);
		} else if (end - begin == 0) {
			return ret;
		}
		try {
			byte[] bytes = source.getBytes(Constants.GB2312_STR);
			String ss = ba2HexString(bytes, begin, end - begin);
			byte[] b1 = hexString2Ba(ss);
			ret = new String(b1, Constants.GB2312_STR);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return ret;

	}

	/*
	 * public static void uploadFileToFtp(String localPath,String ftpPath) {
	 * File f = new File(localPath); FtpUtil ftpUtil = new FtpUtil(); try {
	 * ftpUtil
	 * .uploadFile(f.getName(),"114.242.105.164",21,"jiangsu","J!@n9su",ftpPath
	 * ,new FileInputStream(f)); } catch (NumberFormatException e) {
	 * e.printStackTrace(); } catch (FileNotFoundException e) {
	 * e.printStackTrace(); } }
	 */
	/*
	 * 将一个长传的某些位置的长度替换为其他串 原串：source 替换串：repStr 位置数组： position
	 */
	public static String replace(String source, String repStr, int[] position) {
		int repLength = repStr.length();
		int srcLength = length(source);
		for (int i = 0; i < position.length; i++) {
			source = subString(0, position[i], source) + repStr + subString(position[i] + repLength, srcLength, source);
		}
		return source;
	}

	/**
	 * 
	 * @Title: rightPadstr
	 * @Description: 字符串右补充
	 * @param @param source
	 * @param @param length规定的字符串的总长度
	 * @param @param str要补的字符串 例如String str = "admin123";
	 *        System.out.println(StringUtils.rightPad(str, 12,
	 *        "*"));返回的结果admin123****
	 * @param @return 设定文件
	 * @return String 返回类型
	 * @throws
	 */
	public static String rightPadstr(String source, int length, String str) {
		return StringUtils.rightPad(source, length, str);
	}

	/**
	 * 
	 * @Title: lefttPadstr
	 * @Description: 字符串左补充
	 * @param @param source
	 * @param @param length规定的字符串的总长度
	 * @param @param str要补的字符串 例如String str = "admin123";
	 *        System.out.println(StringUtils.leftPad(str, 12,
	 *        "*"));返回的结果****admin123
	 * @param @return 设定文件
	 * @return String 返回类型
	 * @throws
	 */
	public static String lefttPadstr(String source, int length, String str) {
		return StringUtils.leftPad(source, length, str);
	}

	/**
	 * 
	 * @Title: isMobileNO
	 * @Description: 手机号验证
	 * @param @param mobiles
	 * @param @return 设定文件
	 * @return boolean 返回类型
	 * @throws
	 */
	public static boolean isMobileNO(String mobiles) {

		Pattern p = Pattern.compile("^((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(17[0-9])|(18[0-9]))\\d{8}$");

		Matcher m = p.matcher(mobiles);

		// System.out.println(m.matches()+"---");

		return m.matches();

	}

	/**
	 * 校验字符串是大写
	 * 
	 * @param word
	 * @return
	 */
	public static boolean isAcronym(String word) {
		for (int i = 0; i < word.length(); i++) {
			char c = word.charAt(i);
			if (!Character.isLowerCase(c)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 非空返回false
	 * 
	 * @Title:
	 * @Description: TODO
	 * @param
	 * @param str
	 * @param
	 * @return
	 * @return 返回类型
	 * @throws
	 */
	public static boolean isBlankOrNull(String str) {
		return "".equals(requote(str)) ? true : false;
	}

	/**
	 * 输入指定字串返回非空字符
	 * 
	 * @param str
	 *            指定字串
	 * @return 返回类型 String 返回非空字符
	 * 
	 */
	public static String requote(String str) {
		if (str == null)
			str = "";
		if ("null".equalsIgnoreCase(str))
			str = "";
		return str;
	}

	/**
	 * 按照报文规则处理16进制字符串转换后是10进制
	 * 
	 * @param x
	 * @return
	 */
	public static BigInteger TransString(String x) {
		byte[] a = hexStringToBytes(x);
		byte[] b = reversBytes(a);// 高低位逆位
		BigInteger xx = HexByteToInt(b);
		// System.out.println(xx);
		return xx;
	}

	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.toUpperCase().replace(" ", "");
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	public static byte[] reversBytes(byte[] b) {
		for (int start = 0, end = b.length - 1; start < end; start++, end--) {
			byte temp = b[end];
			b[end] = b[start];
			b[start] = temp;
		}
		return b;
	}

	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	public static BigInteger HexByteToInt(byte[] b) {
		String temp = bytes2HexString(b);
		BigInteger srch = new BigInteger(temp, 16);
		return srch;
	}

	/*
	 * 字节数组转16进制字符串
	 */
	public static String bytes2HexString(byte[] b) {
		String r = "";

		for (int i = 0; i < b.length; i++) {
			String hex = Integer.toHexString(b[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			r += hex.toUpperCase();
		}

		return r;
	}

	/**
	 * 校验字符串是不是数字
	 * 
	 * @param username
	 * @return
	 */
	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	public static boolean validateUserName(String username) {
		Pattern p = Pattern.compile("^[a-z0-9_-]{3,15}$", Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(username);
		return m.matches();
	}

	public static void main(String[] args) {
		String str = "jj";
		System.out.println(StringTools.mkString("123"));
	}
}
